#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "data.h"

/*-------------------------------------*/
void InsertArticle(ABR_Art **la,ARTICLE a)
{
    if(*la)
    {
        if(((*la)->art.idArticle)<=(a.idArticle))
            InsertArticle(&((*la)->droite),a);
        else
            InsertArticle(&((*la)->gauche),a);

    }
    else
    {
        *la=(ABR_Art*)malloc(sizeof(ABR_Art));
        (*la)->art=a;
        (*la)->gauche = (*la)->droite = NULL;
    }
}
/*-------------------------------------*/
void InsertFamille(ABR_FM **lf,FAMILLE f)
{
    if(*lf)
    {
        if(((*lf)->fm.idFamille)<=(f.idFamille))
            InsertFamille(&((*lf)->droite),f);
        else
            InsertFamille(&((*lf)->gauche),f);

    }
    else
    {
        *lf=(ABR_FM*)malloc(sizeof(ABR_FM));
        (*lf)->fm=f;
        (*lf)->gauche = (*lf)->droite = NULL;
    }
}
/*-------------------------------------*/
void InsertFournisseur(ABR_FR **lfr,FOURNISSEUR f)
{
    if(*lfr)
    {
        if(((*lfr)->fr.idFournisseur)<=(f.idFournisseur))
            InsertFournisseur(&((*lfr)->droite),f);
        else
            InsertFournisseur(&((*lfr)->gauche),f);

    }
    else
    {
        *lfr=(ABR_FR*)malloc(sizeof(ABR_FR));
        (*lfr)->fr=f;
        (*lfr)->gauche = (*lfr)->droite = NULL;
    }
}
/*-------------------------------------*/
ABR_Art* LoadArticle(char *filename)
{
    FILE *fp = NULL; char s[50]; ARTICLE a; ABR_Art *la = NULL;

    fp = fopen(filename, "r");
    if(!fp) exit(0);
    while(fgets(s,50,fp))
    {
        sscanf(s,"%5d%15s%5d%5d%5d%5d",&(a.idArticle),(a.designArticle),&(a.prixAchat),&(a.CodeFamille),&(a.qtStock),&(a.codeFournisseur));
        InsertArticle(&la,a);
    }
    return(la);
}
/*-------------------------------------*/
ABR_FM* LoadFamille(char *filename)
{
    FILE *fp = NULL; char s[50]; FAMILLE f; ABR_FM *lf = NULL;

    fp = fopen(filename, "r");
    if(!fp) exit(0);
    while(fgets(s,50,fp))
    {
        sscanf(s,"%5d%15s",&(f.idFamille),(f.designation));
        InsertFamille(&lf,f);
    }
    return(lf);
}
/*-------------------------------------*/
ABR_FR* LoadFournisseur(char *filename)
{
    FILE *fp = NULL; char s[50]; FOURNISSEUR f; ABR_FR *lfr = NULL;

    fp = fopen(filename, "r");
    if(!fp) exit(0);
    while(fgets(s,50,fp))
    {
        sscanf(s,"%5d%15s",&(f.idFournisseur),(f.RaisonSociale));
        InsertFournisseur(&lfr,f);
    }
    return(lfr);
}
/*-------------------------------------*/
ARBRE* SeekNode(ARBRE *racine, int key)
{
    ARBRE *p;
    if(racine)
    {
        if((racine->d.idComposant)==key)
            return (racine);
        if(p = SeekNode((racine->frere),key))
            return(p);
        return(SeekNode(racine->fils,key));
    }
    return(NULL);
}
/*-------------------------------------*/
ARBRE* InsertNode(ARBRE *racine, PRODUIT prod)
{
    ARBRE *pere, *p=NULL;
    p = (ARBRE*)malloc(sizeof(ARBRE));
    p->d = prod;
    p->fils = NULL;
    if((pere = SeekNode(racine,(prod.idCompose))))
    {
        p->frere = pere->fils;
        pere->fils=p;
    }
    else
    {
        p->frere = racine;
        racine = p;
    }
    return(racine);
}
/*-------------------------------------*/
ARBRE* LoadProcede(char *filename)
{
    FILE *fp = NULL; char s[50]; PRODUIT prod; ARBRE *abr=NULL;

    fp = fopen(filename, "r");
    if(!fp) exit(0);
    while(fgets(s,50,fp))
    {
        sscanf(s,"%5d%5d%5d",&(prod.idCompose),&(prod.idComposant),&(prod.quantite));
        abr = InsertNode(abr,prod);
    }
    return(abr);
}
/*-------------------------------------*/
int PrixUnit(ABR_Art *FirstArt, int id)
{
    if(FirstArt)
    {
        if(FirstArt->art.idArticle == id)
            return(FirstArt->art.prixAchat);
        if(FirstArt->art.idArticle < id)
            return(PrixUnit(FirstArt->droite,id));
        return(PrixUnit(FirstArt->gauche,id));
    }
    return(0);
}
/*-------------------------------------*/
int CalculeProd(ARBRE *racine, ABR_Art *FirstArt)
{
    int s=0;

    if(racine)
    {
        printf("[%d]\t\t %d\n",racine->d.quantite,racine->d.idComposant);
        if(racine->fils)
        {
            s = CalculeProd(racine->fils,FirstArt);
            s = s*(racine->d.quantite);
            if(racine->frere)
                s = s + CalculeProd(racine->frere,FirstArt);
            return (s);
        }
        if(racine->frere)
        {
            s = CalculeProd(racine->frere,FirstArt);
            s = s + ((racine->d.quantite)*(PrixUnit(FirstArt,(racine->d.idComposant))));
            return(s);
        }
        return ((racine->d.quantite)*(PrixUnit(FirstArt,(racine->d.idComposant))));
    }
    return(0);
}
/*-------------------------------------*/
void InfoProd(ARBRE *racine,int idProd, ABR_Art *FirstArt)
{
    int Somme; ARBRE *node;
    node = SeekNode(racine, idProd);
    if(node)
        {
            if(!(node->fils))
                printf("%d est un article dont le prix unitaire et de %d",idProd,PrixUnit(FirstArt, idProd));
            else
            {
                printf("Voilà la composition du produit %d : \n",idProd);
                printf("Quantite\t Code Composant\n");
                Somme = CalculeProd(node->fils,FirstArt);
                printf("\nLe cout matiere de ce produit est de : %d\n",Somme);
            }
        }
    else
        printf("Produit n'existe pas !");
}
/*-------------------------------------*/
void InfoArt(ABR_Art *FirstArt,int idFam,int **NbArt)
{
    if(FirstArt)
    {
        InfoArt(FirstArt->gauche,idFam, &(*NbArt));
        if(FirstArt->art.CodeFamille == idFam)
        {
            printf("%s\t\t%d\n",FirstArt->art.designArticle,FirstArt->art.prixAchat);
            (*NbArt)++;
        }
        InfoArt(FirstArt->droite,idFam, &(*NbArt));
    }
}
/*---------------------------------------------*/
ABR_FM *SeekFam(ABR_FM *FirstFm,int idFam)
{
    if(FirstFm)
    {
        if(FirstFm->fm.idFamille == idFam)
            return(FirstFm);
        if(FirstFm->fm.idFamille < idFam)
            return(SeekFam(FirstFm->droite,idFam));
        return(SeekFam(FirstFm->gauche,idFam));
    }
    return(NULL);
}
/*-------------------------------------*/
ABR_Art *SeekArt(ABR_Art *FirstArt, int id)
{
    if(FirstArt)
    {
        if(FirstArt->art.idArticle == id)
            return(FirstArt);
        if(FirstArt->art.idArticle < id)
            return(SeekArt(FirstArt->droite,id));
        return(SeekArt(FirstArt->gauche,id));
    }
    return(NULL);
}
/*-------------------------------------*/
void Insert(ABR_Art *FirstArt, LISTE **list, int id)
{
    LISTE *p, *l;
    p = (LISTE*)malloc(sizeof(LISTE));
    l = SeekArt(FirstArt,id);
    p->art = l->art;
    p->next = *list;
    *list = p;
}
/*-------------------------------------*/
void SeekFeuille(ARBRE *racine, ABR_Art *FirstArt, LISTE **liste)
{
    if(racine)
    {
        if(!(racine->fils))
            Insert(FirstArt,liste,racine->d.idComposant);
        SeekFeuille(racine->frere,FirstArt,liste);
        SeekFeuille(racine->fils,FirstArt,liste);
    }
}
/*-------------------------------------*/
int ExistArt(LISTE *list,int id)
{
    LISTE *t=list;
    while(t && ((t->art.idArticle!=id)))
        t = t->next;
    if(t)
        return 1;
    return 0;
}
/*-------------------------------------*/
void CheckArt(ABR_Art *FirstArt,LISTE *list,int idFam, int **i)
{
    if(FirstArt)
    {
        CheckArt(FirstArt->gauche,list, idFam, &(*i));
        if((FirstArt->art.CodeFamille==idFam)&&!(ExistArt(list,(FirstArt->art.idArticle))))
        {
            printf("Code Article : %d\n",FirstArt->art.idArticle);
            (*i)++;
        }
        CheckArt(FirstArt->droite,list, idFam, &(*i));
    }
}
/*-------------------------------------*/
void NbArticle(int idFr, ABR_Art *FirstArt, int **i)
{
    if(FirstArt)
    {
        NbArticle(idFr, FirstArt->gauche,&(*i));
        if(FirstArt->art.codeFournisseur == idFr)
            (*i)++;
        NbArticle(idFr, FirstArt->droite,&(*i));
    }
}
/*-------------------------------------*/
void *SeekFr(ABR_FR *FirstFr, ABR_Art *FirstArt)
{
    int i = 0;
    if(FirstFr)
    {
        SeekFr(FirstFr->gauche, FirstArt);
        NbArticle(FirstFr->fr.idFournisseur, FirstArt,&i);
        printf("%d\t\t\t%d\n",FirstFr->fr.idFournisseur,i/3);
        SeekFr(FirstFr->droite, FirstArt);
    }
    return(NULL);

}
/*-------------------------------------*/
void NbArticleList(int idFr, LISTE *list, int **i)
{
    while(list)
    {
        if(list->art.codeFournisseur == idFr)
            (*i)++;
        list = list->next;
    }
}
/*-------------------------------------*/
void SeekFrProd(ABR_FR *FirstFr,LISTE *list)
{
    int i = 0;
    if(FirstFr)
    {
        SeekFrProd(FirstFr->gauche, list);
        NbArticleList(FirstFr->fr.idFournisseur, list,&i);
        printf("%d\t\t\t%d\n",FirstFr->fr.idFournisseur,i/4);
        SeekFrProd(FirstFr->droite, list);
    }
    return(NULL);

}
/*-------------------------------------*/
int InfoStock(ABR_Art *FirstArt, int idArt, int quantite)
{
    int reste;
    if(FirstArt)
    {
        if(FirstArt->art.idArticle == idArt)
        {
            FirstArt->art.qtStock = FirstArt->art.qtStock-quantite;
            reste=FirstArt->art.qtStock;
            if(FirstArt->art.qtStock<=0)
                FirstArt->art.qtStock=0;
            return(reste);
        }
        if(FirstArt->art.idArticle < idArt)
            return InfoStock(FirstArt->droite, idArt, quantite);
        return InfoStock(FirstArt->gauche, idArt, quantite);
    }
    return 0;
}
/*-------------------------------------*/
void checkProd(ARBRE *racine, ABR_Art *FirstArt, int q)
{
    int Qdisp;

    if(racine)
    {
        if(!(racine->fils))
        {
            printf("[%d]\t\t%d\t\t",(racine->d.quantite*q),racine->d.idComposant);
            Qdisp = InfoStock(FirstArt,(racine->d.idComposant),(racine->d.quantite*q));
            if(Qdisp>=0)
                printf("0\n");
            else
                printf("%d\n",abs(Qdisp));
        }
        checkProd(racine->frere,FirstArt,q);
        checkProd(racine->fils,FirstArt,q);
    }
}
/*-------------------------------------*/
int main(int argc, char* argv)
{
    ABR_Art *FirstArt; ABR_FM *FirstFm; ABR_FR *FirstFr; ARBRE *racine,*node; LISTE *list=NULL;
    int idProd=1; int idFam=15000; int idFr=24000; int NbArt=0,i=0; int idArt =1500; int q;

    FirstArt = LoadArticle("article.txt");
    FirstFm  = LoadFamille("famille.txt");
    FirstFr  = LoadFournisseur("fournisseur.txt");
    racine   = LoadProcede("procede.txt");
    SeekFeuille(racine,FirstArt,&list);

printf("%d",argc);
/*Reponce Question 1*/
    InfoProd(racine,idProd,FirstArt);
/*Reponce Question 2*/
    if(SeekFam(FirstFm,idFam))
    {
        printf("Designation\t\tCoût Matière\n\n");
        InfoArt(FirstArt, idFam, &NbArt);
        if(!NbArt)
            printf("Aucun article ne correspond à cette famille !\n");
    }
    else
        printf("Vérifiez le code de famille !");
//Reponce Question 3
    if(SeekFam(FirstFm,idFam))
    {
        CheckArt(FirstArt,list,idFam,&i);
        if(!i)
            printf("Tout les articles de la famille %d sont utilisés",idFam);
    }
    else
        printf("Vérifiez le code de famille !");
//Reponce Question 4
printf("\tComposition totale\n");
printf("Code Fournisseur\tNombre d'articles\n");
SeekFr(FirstFr,FirstArt);
printf("\n\tComposition des Produits\n");
printf("Code Fournisseur\tNombre d'articles\n");
SeekFrProd(FirstFr,list);
//Reponse Question 5
node=SeekNode(racine, 1);
printf("\nEtude de faisabilité de %d produit(s) de type 1\n\n",10);
printf("Quantite\tidArticle\tQuantite manquante\n");
checkProd(node->fils, FirstArt,10);
node=SeekNode(racine, 2);
printf("\nEtude de faisabilité de %d produit(s) de type 2\n\n",5);
printf("Quantite\tidArticle\tQuantite manquante\n");
checkProd(node->fils, FirstArt,5);
node=SeekNode(racine, 3);
printf("\nEtude de faisabilité de %d produit(s) de type 3\n\n",2);
printf("Quantite\tidArticle\tQuantite manquante\n");
checkProd(node->fils, FirstArt,2);
}
